package org.xp.judgeplatform.controller;

import jakarta.validation.Valid;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.*;
import org.xp.judgeplatform.common.ApiResponse;
import org.xp.judgeplatform.common.PageResult;
import org.xp.judgeplatform.exception.BusinessException;
import org.xp.judgeplatform.pojo.dto.ProblemSetDTO.*;
import org.xp.judgeplatform.pojo.vo.ProblemSetVO.InviteCodeVO;
import org.xp.judgeplatform.pojo.vo.ProblemSetVO.ProblemSetMemberVO;
import org.xp.judgeplatform.pojo.vo.ProblemSetVO.ProblemSetVO;
import org.xp.judgeplatform.service.ProblemSetService;

@Slf4j
@AllArgsConstructor
@RestController
@RequestMapping("/problemSet")
@CrossOrigin(origins = {"http://localhost:5173"})
public class ProblemSetController {

    private final ProblemSetService problemSetService;

    /**
     * 创建题目集（仅管理员）
     */
    @PostMapping
    @PreAuthorize("hasAuthority('ADMIN')")
    public ApiResponse<ProblemSetVO> createProblemSet(@Valid @RequestBody ProblemSetCreateDTO createDTO,
                                                      Authentication authentication) {
        Integer userId = getCurrentUserId(authentication);
        log.info("用户 {} 创建题目集: {}", userId, createDTO.getName());
        
        ProblemSetVO result = problemSetService.createProblemSet(createDTO, userId);
        return ApiResponse.success(result);
    }

    /**
     * 获取题目集列表
     */
    @GetMapping("/list")
    public ApiResponse<PageResult<ProblemSetVO>> getProblemSetList(ProblemSetQueryDTO queryDTO,
                                                                   Authentication authentication) {
        Integer userId = getCurrentUserId(authentication);
        
        // 参数默认值
        if (queryDTO.getPageNum() == null || queryDTO.getPageNum() < 1) {
            queryDTO.setPageNum(1);
        }
        if (queryDTO.getPageSize() == null || queryDTO.getPageSize() < 1) {
            queryDTO.setPageSize(10);
        }
        
        PageResult<ProblemSetVO> result = problemSetService.getProblemSetList(queryDTO, userId);
        return ApiResponse.success(result);
    }

    /**
     * 管理员获取题目集列表
     */
    @GetMapping("/admin/list")
    @PreAuthorize("hasAuthority('ADMIN')")
    public ApiResponse<PageResult<ProblemSetVO>> getProblemSetsForAdmin(ProblemSetQueryDTO queryDTO) {
        // 参数验证
        if (queryDTO.getPageNum() == null || queryDTO.getPageNum() < 1) {
            queryDTO.setPageNum(1);
        }
        if (queryDTO.getPageSize() == null || queryDTO.getPageSize() < 1) {
            queryDTO.setPageSize(10);
        }

        log.info("管理员查询题目集列表: {}", queryDTO);
        PageResult<ProblemSetVO> result = problemSetService.getProblemSetListForAdmin(queryDTO);
        return ApiResponse.success(result);
    }

    /**
     * 获取题目集详情
     */
    @GetMapping("/{id}")
    public ApiResponse<ProblemSetVO> getProblemSetDetail(@PathVariable Long id,
                                                        Authentication authentication) {
        Integer userId = getCurrentUserId(authentication);
        ProblemSetVO result = problemSetService.getProblemSetDetail(id, userId);
        return ApiResponse.success(result);
    }

    /**
     * 通过邀请码加入题目集
     */
    @PostMapping("/join")
    public ApiResponse<Void> joinProblemSet(@Valid @RequestBody ProblemSetJoinDTO joinDTO,
                                           Authentication authentication) {
        Integer userId = getCurrentUserId(authentication);
        log.info("用户 {} 尝试加入题目集，邀请码: {}", userId, joinDTO.getInviteCode());
        
        problemSetService.joinProblemSet(joinDTO, userId);
        return ApiResponse.success();
    }

    /**
     * 生成邀请码（支持永久和临时，仅创建者）
     */
    @PostMapping("/{id}/invite")
    public ApiResponse<InviteCodeVO> generateInviteCode(
            @PathVariable Long id,
            @Valid @RequestBody InviteCodeDTO dto,
            Authentication authentication) {
        Integer userId = getCurrentUserId(authentication);
        log.info("用户 {} 为题目集 {} 生成邀请码", userId, id);

        InviteCodeVO result = problemSetService.generateInviteCode(id, dto, userId);
        return ApiResponse.success(result);
    }

    /**
     * 获取题目集成员列表
     */
    @GetMapping("/{id}/members")
    public ApiResponse<PageResult<ProblemSetMemberVO>> getMembers(@PathVariable Long id,
                                                                  @RequestParam(defaultValue = "1") Integer pageNum,
                                                                  @RequestParam(defaultValue = "10") Integer pageSize,
                                                                  Authentication authentication) {
        Integer userId = getCurrentUserId(authentication);
        PageResult<ProblemSetMemberVO> result = problemSetService.getMembers(id, pageNum, pageSize, userId);
        return ApiResponse.success(result);
    }

    /**
     * 更新题目集（仅创建者）
     */
    @PutMapping("/{id}")
    public ApiResponse<ProblemSetVO> updateProblemSet(@PathVariable Long id,
                                                      @Valid @RequestBody ProblemSetUpdateDTO updateDTO,
                                                      Authentication authentication) {
        Integer userId = getCurrentUserId(authentication);
        log.info("用户 {} 更新题目集 {}", userId, id);
        
        ProblemSetVO result = problemSetService.updateProblemSet(id, updateDTO, userId);
        return ApiResponse.success(result);
    }

    /**
     * 删除题目集（软删除，仅创建者）
     */
    @DeleteMapping("/{id}")
    public ApiResponse<Void> deleteProblemSet(@PathVariable Long id,
                                             Authentication authentication) {
        Integer userId = getCurrentUserId(authentication);
        log.info("用户 {} 删除题目集 {}", userId, id);
        
        problemSetService.deleteProblemSet(id, userId);
        return ApiResponse.success();
    }

    /**
     * 为题目集添加题目（管理员）
     */
    @PostMapping("/{id}/problems")
    public ApiResponse<Void> addProblemToSet(@PathVariable Long id,
                                            @Valid @RequestBody ProblemSetAddItemDTO addItemDTO,
                                            Authentication authentication) {
        Integer userId = getCurrentUserId(authentication);
        log.info("用户 {} 为题目集 {} 添加题目", userId, id);
        
        problemSetService.addProblemToSet(id, addItemDTO, userId);
        return ApiResponse.success();
    }

    /**
     * 获取当前登录用户ID
     */
    private Integer getCurrentUserId(Authentication authentication) {
        if (authentication == null || authentication.getPrincipal() == null) {
            throw new BusinessException(401, "未登录或登录已过期");
        }
        if (authentication.getPrincipal() instanceof org.xp.judgeplatform.security.UserPrincipal userPrincipal) {
            return userPrincipal.getId();
        }
        throw new BusinessException(401, "无法获取用户信息");
    }
}